home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 191_01 / clink.c < prev    next >
C/C++ Source or Header  |  1986-07-08  |  17KB  |  496 lines

  1. /* CLINK       6-9-85 ported to Mix C  5-31-86       */
  2. /* Linkage of C source code subroutines              */
  3. /* Phillip L. Emerson    Cleveland State University  */
  4.  
  5.       /* some modifiable parameters */
  6. #define SAME 0
  7. #define LESS -1
  8. #define MORE 1
  9. #define ONE 1
  10. #define VOID -1
  11. #define UNDRSC '\137'   /* ASCII special characters */
  12. #define BELL '\007'
  13. #define APOSTR '\047'
  14. #define QUOTE '\042'
  15. #define BACKSL '\134'
  16. #define LF '\n'
  17. #define SP '\40'
  18. #define BUFSZ 5000       /*must hold any lib. func.  */
  19. #define NAMSIZ 20        /*max length of func. names */
  20. #define HASHSIZ 512      /*size of hash table        */
  21. #define LINSIZ 140       /*source-code max line  ln  */
  22. #define FNAMSZ 20        /*max len. of file names    */
  23. #define OFFSET 20        /*buff offset for backup    */
  24. #define MARGA 10         /*error margin for buff ovfl */
  25. #define MARGB 15         /*error margin for buff ovfl */
  26. #include "stdio"
  27. /*$SIGNEXT*/
  28. /*$ZERO*/
  29. /* Version for Mix C.--  Main changes from C/80 version:
  30.  1. added #include "stdio"
  31.  2. added above two $ comments as Mix compiler parameters
  32.  3. removed #define NULL, which is done in Mix's stdio
  33.  4. changed BUFSIZ to BUFSZ ; BUFSIZ used by Mix's stdio
  34.  5. changed IO type from int to FILE *
  35.  6. changed erroneous instance of linebuff to linebuf
  36.  7. removed #define alloc sbrk & used calloc() instead
  37. */
  38. char progfil[FNAMSZ],libfil[FNAMSZ],keyfil[FNAMSZ],outfil[FNAMSZ];
  39. char *fubuff, *linebuf ;
  40. FILE *prchan,*lichan,*keychan,*ouchan,*fopen(),*foptst();
  41. int quotes,apostrs,combal;
  42. char *calloc() ;
  43. /* some functs. before main */
  44.  
  45. /* next f name into r, from string starting
  46.    at p -- return 0 if end reached */
  47. char *funam(p,r) char *p,*r; {char *t,*q,*s,*u; int n;
  48.   u = r ;
  49. loop: s = p; r = u ;
  50.    while ((*p) && (*p != '(' )) p++ ;
  51.    if (*p == NULL) return(NULL) ;
  52.    t = p-- ;
  53.    while ((*p == ' ' ) && (p > s)) p-- ;
  54.    q = p ;
  55.    if( !lglname(*q)) { p = ++t ; goto loop ; }
  56.    while ( lglname(*q) && (q >= s)) q-- ;
  57.    q++ ;
  58.    for(n=1; (n < (NAMSIZ-1)) && (q <= p); *r++ = *q++,n++) ;
  59.    *r = NULL;
  60.    if ((q < s) || (n >= (NAMSIZ-1)) || (n <= 0))
  61.       {putstr("error in processing name\n") ;
  62.        putstr(u); putchar(LF); exit(); }
  63.    if (systn(u)) { p = ++t; goto loop; }
  64.    return(++t) ; }
  65.  
  66. /* list of commen system function names to ignore */
  67. #define SNAMES 19  /* nr of names*/
  68. char *sysnam(n) int n;
  69. {static char *name[] = {
  70. "if","for","while","fclose","fopen","getc",
  71. "putc","write","read","getchar","putchar",
  72. "alloc","return","main","seek","ftell",
  73. "ftellr","exec","switch" } ; return(name[n]) ; }
  74.  
  75. /* Mod2 counting of apostrophes and quotes */
  76. char quotap(n) char n; {static char last;
  77.   if(( n == QUOTE) && (last != BACKSL ) && !apostrs)
  78.      quotes = ((quotes+1) % 2) ;
  79.   if(( n == APOSTR) && (last != BACKSL) && !quotes)
  80.      apostrs=((apostrs+1) % 2) ;
  81.   last = n ;
  82.   return(n) ; }
  83.  
  84. /* allocate space for s, store s, and return ptr to it */
  85. char *strsave(s) char *s; {char *p ;
  86.    if (((p=calloc(1,strlen(s)+1)) == VOID) || (p == NULL))
  87.           return(NULL) ;
  88.    strcpy(p,s); return(p) ; }
  89.  
  90. /* search for string q on p. rtrn ptr to it if so, null if not*/
  91. char *strison(p,q) char *p,*q; {
  92.    for( ; *p ; p++) {if(strisat(p,q)) return(p) ; }
  93.    return(NULL) ; }
  94.  
  95. /* standard getch & ungetch to be used in next routine*/
  96. int getctr ;
  97. char getcbuf[5] ;
  98. char getch()
  99.   { if(getctr) return (getcbuf[--getctr]); return(getc(lichan)) ; }
  100. ungetch(a) char a;
  101.   {getcbuf[getctr++] = a; return; }
  102.  
  103. /* get a char from libchan, ignoring literals & comments */
  104. char gignor()
  105. { char n,m;
  106. loop1: if ((n=getch()) == VOID) return(VOID) ;
  107.    if((n != '/') || quotes || apostrs) return(quotap(n)) ;
  108.    if((m=getch()) != '*') {ungetch(m) ; return(quotap(n)) ; }
  109. loop2: while (((m=getch()) != '*') && (m != VOID))
  110.         {n=getch(); ungetch(n);
  111.          if((m == '/') && (n == '*')) combal++ ; }
  112.    if (m == VOID) return(VOID) ;
  113.    if((m=getch()) != '/') {ungetch(m) ; goto loop2; }
  114.    goto loop1; }
  115.  
  116. oulab() {putl("/* file ",ouchan);putl(outfil,ouchan);putl(" */\n",ouchan);}
  117.  
  118. struct list {
  119. char *hashkey ;
  120. char *defntn ;
  121. struct list *next ; } ;
  122. struct list **table1 ;
  123. struct list **table2 ;
  124.  
  125. /*  BEGINNING OF MAIN PROGRAM */
  126. main(argc,argv) int argc; char *argv[];
  127. {
  128.   putstr("CLINK  v. 6-9-85 ported to Mix C 5-31-86\n") ;
  129.   linebuf = calloc(1,LINSIZ) ;
  130.   table1 = (struct list **) calloc(1,HASHSIZ*(sizeof(struct list *))) ;
  131.   table2 = (struct list **) calloc(1,HASHSIZ*(sizeof(struct list *))) ;
  132.   tabinit() ;
  133.   fubuff = calloc(1,BUFSZ) ;
  134.   if( (fubuff == NULL) || (fubuff == VOID))
  135.     {putstr("not enough room for buffer\n"); exit(); }
  136.   strcpyn(progfil,argv[1],FNAMSZ-1) ;
  137.   strcpyn(libfil,argv[2],FNAMSZ-1) ;
  138.   strcpyn(keyfil,argv[3],FNAMSZ-1) ;
  139.   strcpyn(outfil,argv[4],FNAMSZ-1) ;
  140.   if (argc >= 2)
  141.       { if ( !strison(progfil,"."))
  142.             strcpy(progfil+strlen(progfil),".B") ;
  143.         if (argc < 5) strcpyc(outfil,progfil,'.') ;
  144.         if (argc < 4) strcpy(keyfil,"LIBKEY.B") ;
  145.         if (argc < 3) strcpy(libfil,"USRLIB.B") ;
  146.         defalt(progfil,keyfil,".B") ;
  147.         defalt(progfil,libfil,".B") ;
  148.         defalt(progfil,outfil,".C") ;
  149.         putchar(LF) ;
  150.         putstr(progfil) ; putstr(" program file\n") ;
  151.         putstr(libfil) ; putstr(" library file\n") ;
  152.         putstr(keyfil) ; putstr(" library key file\n") ;
  153.         putstr(outfil) ; putstr(" output file \n") ;
  154.         putstr("press RETURN (or ENTER) to proceed, Ctrl-C to abort\n") ;
  155.         getchar() ;
  156.         hashup() ;
  157.         prchan = foptst(progfil,"r") ;
  158.         ouchan = foptst(outfil,"w") ;
  159.         oulab() ;
  160.         buildup(1) ;
  161.      }
  162.  else
  163.      {  putstr("\nlibrary file name? ") ;  getstr(libfil) ;
  164.         putstr("\nlibrary keys file name? "); getstr(keyfil) ;
  165.         putstr("wait -- getting library keys\n") ;
  166.         hashup() ;
  167.         putstr("output file name? ") ;  getstr(outfil) ;
  168.         ouchan = foptst(outfil,"w") ; oulab() ;
  169.         for (*progfil='1'; (*progfil) && (*progfil != LF) ; )
  170.           { putstr("input file name? -- ") ;
  171.             putstr("just press RETURN (or ENTER) if no more ") ;
  172.             *progfil = NULL; getstr(progfil) ;
  173.             if ( (*progfil) && (*progfil != LF ) )
  174.               {prchan = foptst(progfil,"r") ;
  175.                putstr("include in output file? (type 0 for no, 1 for yes)\n");
  176.                buildup(getint()) ;
  177.               }
  178.           }
  179.      }
  180.  tidyup() ;
  181.  if (quotes || apostrs || combal)
  182.      {  putchar(LF); putstr("quotes mod2: ") ; printd(quotes) ;
  183.         putchar(LF); putstr("apostrophes mod2: "); printd(apostrs) ;
  184.         putchar(LF) ;
  185.         putstr("occurrences of comment delimiters within comments: ") ;
  186.         printd(combal) ; putchar(LF) ;
  187.      }
  188.  putstr("Linked output file is "); putstr(outfil); putstr("\n\n") ;
  189. }
  190. /*  END OF MAIN PROGRAM */
  191.  
  192. /*  MANY SUBROUTINES FOLLOW -- some of the more general purpose
  193.     ones would ordinarily reside in a library, but this program
  194.     is intended to be fairly self-contained
  195. */
  196.  
  197. /* Manipulation for defaults on file names */
  198. defalt(fpr,fothr,ext) char *fpr,*fothr,*ext;
  199.   {  char *a,temp[FNAMSZ]; int n;
  200.      if( !strison(fothr,":") && (a = strison(fpr,":") ) )
  201.          {  if ( n = a - fpr)
  202.              {  strcpyn(temp,fpr,n+1) ;
  203.                 strcpy(temp+n+1,fothr) ;
  204.                 strcpy(fothr,temp) ;
  205.              }
  206.          }
  207.      if( !strison(fothr,".") ) strcpy(fothr+strlen(fothr),ext) ;
  208.   }
  209.  
  210. /* copy t to s up to but not including 1st instance of char c */
  211. strcpyc(s,t,c) char *s,*t,c;
  212.   { while( (*s++ = *t++) != c)  ; *(--s) = NULL ; }
  213.  
  214. /* tabinit,hash,look,insert are FUNCTIONS FOR HASHING FUNCTION CALLS UNDER
  215.      FUNCTION NAMES
  216. */
  217.  
  218. tabinit()
  219.   {int n; for (n=0; n < HASHSIZ ; n++) table1[n] = table2[n]=NULL ;}
  220.  
  221. hash(s) char *s; {int val;
  222.   for (val=0; *s ;) val += *s++; return(val % HASHSIZ) ; }
  223. struct list *look(s,table) char *s; struct list **table;
  224.   {struct list *p ;
  225.    for (p=table[hash(s)] ; p ; p = p->next )
  226.      { if (strcmp(s,p->hashkey) == SAME) return(p) ;